﻿using JNPF.Basics.Models;
using JNPF.Basics.Models.WorkFlow.Model;
using JNPF.Utils;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace JNPF.Basics.Logic
{
    /// <summary>
    /// 流程引擎
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2018.01.17 
    /// </summary>
    public class FlowEngineBll
    {
        private FlowEngineIService service = new FlowEngineService();
        private FlowEngineVisibleBll flowEngineVisibleBll = new FlowEngineVisibleBll();


        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<FlowEngineEntity>> GetList()
        {
            try
            {
                return await service.GetList();
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<FlowEngineEntity>> GetFlowFormList()
        {
            try
            {
                var data = new List<FlowEngineEntity>();
                var userInfo = UserProvider.Instance.Get();
                var flowEngineData = (await service.GetList()).FindAll(m => m.EnabledMark == 1 && m.Type == 0);
                if (!userInfo.IsAdministrator)
                {
                    //部分看见
                    var flowVisibleData = await flowEngineVisibleBll.GetVisibleFlowList(userInfo.UserId);
                    //去重
                    var ids = new List<string>();
                    foreach (FlowEngineVisibleEntity item in flowVisibleData)
                    {
                        FlowEngineEntity flowEngineEntity = flowEngineData.Find(m => m.Id == item.FlowId);
                        if (flowEngineEntity != null && !ids.Contains(flowEngineEntity.Id))
                        {
                            data.Add(flowEngineEntity);
                            ids.Add(flowEngineEntity.Id);
                        }
                    }
                    ////全部看见
                    foreach (FlowEngineEntity flowEngineEntity in flowEngineData.FindAll(m => m.VisibleType == 0))
                    {
                        data.Add(flowEngineEntity);
                    }
                }
                else
                {
                    data = flowEngineData;
                }
                return data;
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 信息
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        public async Task<FlowEngineEntity> GetInfo(string id)
        {
            try
            {
                return await service.GetInfo(id);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 信息
        /// </summary>
        /// <param name="enCode">流程编码</param>
        /// <returns></returns>
        public async Task<FlowEngineEntity> GetInfoByEnCode(string enCode)
        {
            try
            {
                return await service.GetInfoByEnCode(enCode);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 重复验证（名称）
        /// </summary>
        /// <param name="fullName">流程名称</param>
        /// <param name="id">键值</param>
        /// <returns></returns>
        public async Task<bool> IsExistByFullName(string fullName, string id)
        {
            try
            {
                var whereLambda = ExtLinq.True<FlowEngineEntity>();
                whereLambda = whereLambda.And(m => m.FullName == fullName);
                if (!string.IsNullOrEmpty(id))
                    whereLambda = whereLambda.And(m => m.Id != id);
                return await service.IsExist(whereLambda);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 重复验证（编码）
        /// </summary>
        /// <param name="enCode">流程编码</param>
        /// <param name="id">键值</param>
        /// <returns></returns>
        public async Task<bool> IsExistByEnCode(string enCode, string id)
        {
            try
            {
                var whereLambda = ExtLinq.True<FlowEngineEntity>();
                whereLambda = whereLambda.And(m => m.EnCode == enCode);
                if (!string.IsNullOrEmpty(id))
                    whereLambda = whereLambda.And(m => m.Id != id);
                return await service.IsExist(whereLambda);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">实体对象</param>
        public async Task Delete(FlowEngineEntity entity)
        {
            try
            {
                await service.Delete(entity);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="visibleList">可见范围</param>
        public async Task Create(FlowEngineEntity entity, List<FlowEngineVisibleEntity> visibleList)
        {
            try
            {
                entity.Id = CommonHelper.Guid;
                entity.CreatorTime = DateTime.Now;
                entity.CreatorUserId = UserProvider.Instance.Get().UserId;
                entity.VisibleType = visibleList.Count == 0 ? 0 : 1;
                await service.Create(entity, visibleList);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id">主键值</param>
        /// <param name="entity">实体对象</param>
        /// <param name="visibleList">可见范围</param>
        public async Task Update(string id, FlowEngineEntity entity, List<FlowEngineVisibleEntity> visibleList)
        {
            try
            {
                entity.Id = id;
                entity.LastModifyTime = DateTime.Now;
                entity.LastModifyUserId = UserProvider.Instance.Get().UserId;
                entity.VisibleType = visibleList.Count == 0 ? 0 : 1;
                await service.Update(entity, visibleList);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id">主键值</param>
        /// <param name="entity">实体对象</param>
        public async Task Update(string id, FlowEngineEntity entity)
        {
            try
            {
                entity.Id = id;
                entity.LastModifyTime = DateTime.Now;
                entity.LastModifyUserId = UserProvider.Instance.Get().UserId;
                await service.Update(entity);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }

        /// <summary>
        /// 获取流程节点
        /// </summary>
        /// <param name="flowTemplateJson"></param>
        /// <returns></returns>
        public long GetFlowNodeList(string stepId, List<FlowTaskNodeEntity> flowTaskNodeList)
        {
            long freeApprover = 0;
            //当前节点是加签
            FlowTaskNodeEntity thisStep = flowTaskNodeList.Find(x => x.NodeCode.Equals(stepId));
            if (thisStep != null)
            {
                ChildNodeModelList thisNode = thisStep.NodePropertyJson.ToObject<ChildNodeModelList>();
                if (thisNode.assigneeType == (int)FlowTaskOperatorEnum.FreeApprover)
                {
                    freeApprover = 1;
                }
                else
                {
                    //下个节点是加签
                    FlowTaskNodeEntity nextStep = flowTaskNodeList.Find(x => x.NodeCode.Equals(thisStep.NodeNext));
                    if (nextStep != null)
                    {
                        ChildNodeModelList nextNode = nextStep.NodePropertyJson.ToObject<ChildNodeModelList>();
                        if (nextNode.assigneeType == (int)FlowTaskOperatorEnum.FreeApprover)
                        {
                            freeApprover = 1;
                        }
                    }
                }
            }
            return freeApprover;
        }




    }
}
